home *** CD-ROM | disk | FTP | other *** search
/ Collection of Tools & Utilities / Collection of Tools and Utilities.iso / graphic / frasr182.zip / LSYS.C < prev    next >
C/C++ Source or Header  |  1993-02-18  |  22KB  |  896 lines

  1. #include <stdio.h>
  2. #include <stdlib.h>
  3. #include <string.h>
  4. #include <math.h>
  5. #ifdef __TURBOC__
  6. #include <alloc.h>
  7. #elif !defined(__386BSD__)
  8. #include <malloc.h>
  9. #endif
  10. #include "fractint.h"
  11. #include "prototyp.h"
  12.  
  13. #define size    ssize
  14. /* Needed for use of asm -- helps decide which pointer to function
  15.  * to put into the struct lsys_cmds.
  16.  */
  17. extern int cpu;
  18. extern int fpu;
  19. extern int debugflag;
  20. extern int xdots,ydots;
  21. extern int colors;
  22. extern char LFileName[];
  23. extern char LName[];
  24. extern double param[];
  25. extern int overflow;
  26. extern float  screenaspect;
  27.  
  28. struct lsys_cmd {
  29.   char ch;
  30.   void (*f)(long n);
  31.   long n;
  32. };
  33.  
  34. static double      _fastcall getnumber(char far **);
  35. static struct lsys_cmd far * _fastcall findsize(struct lsys_cmd far *,struct lsys_cmd far **,int);
  36. static int      _fastcall findscale(struct lsys_cmd far *, struct lsys_cmd far **, int);
  37. static struct lsys_cmd far * _fastcall drawLSys(struct lsys_cmd far *, struct lsys_cmd far **, int);
  38. static int      _fastcall readLSystemFile(char *);
  39. static void      _fastcall free_rules_mem(void);
  40. static int      _fastcall save_rule(char *,char far **);
  41. static struct lsys_cmd far *SizeTransform(char far *s);
  42. static struct lsys_cmd far *DrawTransform(char far *s);
  43. static void free_lcmds();
  44.  
  45. static long aspect; /* aspect ratio of each pixel, ysize/xsize */
  46.  
  47. /* Some notes to Adrian from PB, made when I integrated with v15:
  48.      printfs changed to work with new user interface
  49.      bug at end of readLSystemFile, the line which said rulind=0 fixed
  50.        to say *rulind=0
  51.      the calloc was not worthwhile, it was just for a 54 byte area, cheaper
  52.        to keep it as a static;    but there was a static 201 char buffer I
  53.        changed to not be static
  54.      use of strdup was a nono, caused problems running out of space cause
  55.        the memory allocated each time was never freed; I've changed to
  56.        use far memory and to free when done
  57.    */
  58.  
  59. long sins[50];
  60. long coss[50];
  61. /* dmaxangle is maxangle - 1. */
  62. char maxangle,dmaxangle,curcolor;
  63. long size;
  64. unsigned long realangle;
  65. long xpos,ypos;
  66. char counter,angle,reverse,stackoflow;
  67. long lsys_Xmin, lsys_Xmax, lsys_Ymin, lsys_Ymax;
  68.  
  69. /* Macro to take an FP number and turn it into a
  70.  * 16/16-bit fixed-point number.
  71.  */
  72. #define FIXEDMUL    524288L
  73. #define FIXEDPT(x)    ((long) (FIXEDMUL * (x)))
  74.  
  75. /* The number by which to multiply sines, cosines and other
  76.  * values with magnitudes less than or equal to 1.
  77.  * sins and coss are a 3/29 bit fixed-point scheme (so the
  78.  * range is +/- 2, with good accuracy.    The range is to
  79.  * avoid overflowing when the aspect ratio is taken into
  80.  * account.
  81.  */
  82. #define FIXEDLT1    536870912.0
  83.  
  84. /* Multiply by this number to convert an unsigned 32-bit long
  85.  * to an angle from 0-2PI.
  86.  */
  87. #define ANGLE2DOUBLE    (2*PI / 4294967296.)
  88.  
  89. static int ispow2(long n)
  90. {
  91.   return (n == (n & -n));
  92. }
  93.  
  94.  
  95. #ifdef XFRACT
  96. static void lsys_doplus(long n)
  97. {
  98.   if (reverse) {
  99.     if (++angle == maxangle)
  100.       angle = 0;
  101.   }
  102.   else {
  103.     if (angle)
  104.       angle--;
  105.     else
  106.       angle = dmaxangle;
  107.   }
  108. }
  109. #endif
  110.  
  111.  
  112. #ifdef XFRACT
  113. /* This is the same as lsys_doplus, except maxangle is a power of 2. */
  114. static void lsys_doplus_pow2(long n)
  115. {
  116.   if (reverse) {
  117.     angle++;
  118.     angle &= dmaxangle;
  119.   }
  120.   else {
  121.     angle--;
  122.     angle &= dmaxangle;
  123.   }
  124. }
  125. #endif
  126.  
  127.  
  128. #ifdef XFRACT
  129. static void lsys_dominus(long n)
  130. {
  131.   if (reverse) {
  132.     if (angle)
  133.       angle--;
  134.     else
  135.       angle = dmaxangle;
  136.   }
  137.   else {
  138.     if (++angle == maxangle)
  139.       angle = 0;
  140.   }
  141. }
  142. #endif
  143.  
  144.  
  145. #ifdef XFRACT
  146. static void lsys_dominus_pow2(long n)
  147. {
  148.   if (reverse) {
  149.     angle--;
  150.     angle &= dmaxangle;
  151.   }
  152.   else {
  153.     angle++;
  154.     angle &= dmaxangle;
  155.   }
  156. }
  157. #endif
  158.  
  159. static void lsys_doslash(long n)
  160. {
  161.   if (reverse)
  162.     realangle -= n;
  163.   else
  164.     realangle += n;
  165. }
  166. #ifdef XFRACT
  167. #define lsys_doslash_386 lsys_doslash
  168. #endif
  169.  
  170. static void lsys_dobslash(long n)
  171. {
  172.   if (reverse)
  173.     realangle += n;
  174.   else
  175.     realangle -= n;
  176. }
  177.  
  178. #ifdef XFRACT
  179. #define lsys_dobslash_386 lsys_dobslash
  180. #endif
  181.  
  182. static void lsys_doat(long n)
  183. {
  184.   size = multiply(size, n, 19);
  185. }
  186.  
  187. #ifdef XFRACT
  188. #define lsys_doat_386 lsys_doat
  189. #endif
  190.  
  191. static void lsys_dopipe(long n)
  192. {
  193.   angle += maxangle / 2;
  194.   angle %= maxangle;
  195. }
  196.  
  197.  
  198. #ifdef XFRACT
  199. static void lsys_dopipe_pow2(long n)
  200. {
  201.   angle += maxangle >> 1;
  202.   angle &= dmaxangle;
  203. }
  204. #endif
  205.  
  206.  
  207. #ifdef XFRACT
  208. static void lsys_dobang(long n)
  209. {
  210.   reverse = ! reverse;
  211. }
  212. #endif
  213.  
  214. static void lsys_dosizedm(long n)
  215. {
  216.   double angle = (double) realangle * ANGLE2DOUBLE;
  217.   double s, c;
  218.   long fixedsin, fixedcos;
  219.   FPUsincos(&angle, &s, &c);
  220.   fixedsin = (long) (s * FIXEDLT1);
  221.   fixedcos = (long) (c * FIXEDLT1);
  222.  
  223.   xpos += multiply(multiply(size, aspect, 19), fixedcos, 29);
  224.   ypos += multiply(size, fixedsin, 29);
  225.  
  226. /* xpos+=size*aspect*cos(realangle*PI/180);  */
  227. /* ypos+=size*sin(realangle*PI/180);         */
  228.   if (xpos>lsys_Xmax) lsys_Xmax=xpos;
  229.   if (ypos>lsys_Ymax) lsys_Ymax=ypos;
  230.   if (xpos<lsys_Xmin) lsys_Xmin=xpos;
  231.   if (ypos<lsys_Ymin) lsys_Ymin=ypos;
  232. }
  233.  
  234. static void lsys_dosizegf(long n)
  235. {
  236.   xpos += multiply(size, (long) coss[angle], 29);
  237.   ypos += multiply(size, (long) sins[angle], 29);
  238. /* xpos+=size*coss[angle];                   */
  239. /* ypos+=size*sins[angle];                   */
  240.   if (xpos>lsys_Xmax) lsys_Xmax=xpos;
  241.   if (ypos>lsys_Ymax) lsys_Ymax=ypos;
  242.   if (xpos<lsys_Xmin) lsys_Xmin=xpos;
  243.   if (ypos<lsys_Ymin) lsys_Ymin=ypos;
  244. }
  245.  
  246. #ifdef XFRACT
  247. #define lsys_dosizegf_386 lsys_dosizegf
  248. #endif
  249.  
  250. static void lsys_dodrawd(long n)
  251. {
  252.   double angle = (double) realangle * ANGLE2DOUBLE;
  253.   double s, c;
  254.   long fixedsin, fixedcos;
  255.   int lastx, lasty;
  256.   FPUsincos(&angle, &s, &c);
  257.   fixedsin = (long) (s * FIXEDLT1);
  258.   fixedcos = (long) (c * FIXEDLT1);
  259.  
  260.   lastx=(int) (xpos >> 19);
  261.   lasty=(int) (ypos >> 19);
  262.   xpos += multiply(multiply(size, aspect, 19), fixedcos, 29);
  263.   ypos += multiply(size, fixedsin, 29);
  264. /* xpos+=size*aspect*cos(realangle*PI/180);   */
  265. /* ypos+=size*sin(realangle*PI/180);          */
  266.   draw_line(lastx,lasty,(int)(xpos >> 19),(int)(ypos>>19),curcolor);
  267. }
  268.  
  269. static void lsys_dodrawm(long n)
  270. {
  271.   double angle = (double) realangle * ANGLE2DOUBLE;
  272.   double s, c;
  273.   long fixedsin, fixedcos;
  274.   FPUsincos(&angle, &s, &c);
  275.   fixedsin = (long) (s * FIXEDLT1);
  276.   fixedcos = (long) (c * FIXEDLT1);
  277.  
  278. /* xpos+=size*aspect*cos(realangle*PI/180);   */
  279. /* ypos+=size*sin(realangle*PI/180);          */
  280.   xpos += multiply(multiply(size, aspect, 19), fixedcos, 29);
  281.   ypos += multiply(size, fixedsin, 29);
  282. }
  283.  
  284. static void lsys_dodrawg(long n)
  285. {
  286.   xpos += multiply(size, (long) coss[angle], 29);
  287.   ypos += multiply(size, (long) sins[angle], 29);
  288. /* xpos+=size*coss[angle];                    */
  289. /* ypos+=size*sins[angle];                    */
  290. }
  291.  
  292. #ifdef XFRACT
  293. #define  lsys_dodrawg_386 lsys_dodrawg
  294. #endif
  295.  
  296. static void lsys_dodrawf(long n)
  297. {
  298.   int lastx = (int) (xpos >> 19);
  299.   int lasty = (int) (ypos >> 19);
  300.   xpos += multiply(size, (long) coss[angle], 29);
  301.   ypos += multiply(size, (long) sins[angle], 29);
  302. /* xpos+=size*coss[angle];                    */
  303. /* ypos+=size*sins[angle];                    */
  304.   draw_line(lastx,lasty,(int)(xpos>>19),(int)(ypos>>19),curcolor);
  305. }
  306.  
  307. static void lsys_dodrawc(long n)
  308. {
  309.   curcolor = ((int) n) % colors;
  310. }
  311.  
  312. static void lsys_dodrawgt(long n)
  313. {
  314.   curcolor -= n;
  315.   if ((curcolor &= colors-1) == 0)
  316.     curcolor = colors-1;
  317. }
  318.  
  319. static void lsys_dodrawlt(long n)
  320. {
  321.   curcolor += n;
  322.   if ((curcolor &= colors-1) == 0)
  323.     curcolor = 1;
  324. }
  325.  
  326. static double _fastcall getnumber(char far **str)
  327. {
  328.    char numstr[30];
  329.    float ret;
  330.    int i,root,inverse;
  331.  
  332.    root=0;
  333.    inverse=0;
  334.    strcpy(numstr,"");
  335.    (*str)++;
  336.    switch (**str)
  337.    {
  338.    case 'q':
  339.       root=1;
  340.       (*str)++;
  341.       break;
  342.    case 'i':
  343.       inverse=1;
  344.       (*str)++;
  345.       break;
  346.    }
  347.    switch (**str)
  348.    {
  349.    case 'q':
  350.       root=1;
  351.       (*str)++;
  352.       break;
  353.    case 'i':
  354.       inverse=1;
  355.       (*str)++;
  356.       break;
  357.    }
  358.    i=0;